﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using BalanceManager.Helpers;
using BalanceManager.Model;
using BalanceManager.ViewModels;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using GestureEventArgs = System.Windows.Input.GestureEventArgs;

namespace BalanceManager.Views
{
    public partial class ItemsView : BindablePage
    {
        ApplicationBarIconButton selectNodeButton;
        Stack<TreeNode<Item>> _nodesStack = new Stack<TreeNode<Item>>();


        public ItemsView()
        {
            InitializeComponent();

            treeListControl.ItemRealized += treeListControl_ItemRealized;
            treeListControl.ItemUnrealized += treeListControl_ItemUnrealized;
        }

        void treeListControl_ItemUnrealized(object sender, ItemRealizationEventArgs e)
        {
            var contextMenu = ContextMenuService.GetContextMenu(e.Container);
            var menu = contextMenu.Items[1] as MenuItem;
            menu.Click -= MenuItem_Edit_OnClick;
        }

        void treeListControl_ItemRealized(object sender, ItemRealizationEventArgs e)
        {
            var item = (e.Container.Content as TreeNode<Item>).Item;
            var contextMenu = new ContextMenu();

            var deleteMenuItem = new MenuItem {Header = "Удалить"};
            deleteMenuItem.Command = (DataContext as ItemsViewModel).DeleteItemCommand;
            deleteMenuItem.CommandParameter = item;
            
            var editMenuItem = new MenuItem {Header = "Изменить", Tag = item};
            editMenuItem.Click += MenuItem_Edit_OnClick;

            contextMenu.Items.Add(editMenuItem);
            contextMenu.Items.Add(deleteMenuItem);
            ContextMenuService.SetContextMenu(e.Container, contextMenu);
        }

        void CreateSelectButton()
        {
            selectNodeButton = new ApplicationBarIconButton()
            { 
                IconUri = new Uri("/Images/check.png", UriKind.Relative),
                IsEnabled = false,
                Text = "Выбрать"
            };
            selectNodeButton.Click += SelectNodeButtonOnClick;
            ApplicationBar.Buttons.Add(selectNodeButton);
        }

        void SelectNodeButtonOnClick(object sender, EventArgs eventArgs)
        {
            (DataContext as ItemsViewModel).SelectItemCommand.Execute(null);
        }

        void TreeListControl_OnTap(object sender, GestureEventArgs e)
        {
            var control = sender as LongListSelector;
            var selectedItem = control.SelectedItem as TreeNode<Item>;
            if (selectedItem == null || (_nodesStack.Count > 0 && selectedItem == _nodesStack.Peek())) return;

            control.ItemsSource = selectedItem.Children;
            _nodesStack.Push(selectedItem);
            (DataContext as ItemsViewModel).SelectedNode = selectedItem;
        }

        void ApplicationBarIconButtonAdd_OnClick(object sender, EventArgs e)
        {
            var textBox = new TextBox();
            textBox.InputScope = new InputScope { Names = { new InputScopeName { NameValue = InputScopeNameValue.Chat } } };

            var msg = new CustomMessageBox()
            {
                Title = "Добавление категории",
                Caption = "Введите наименование категории",
                Content = textBox,
                LeftButtonContent = "ОК",
                RightButtonContent = "Отмена",
                IsFullScreen = false
            };

            msg.Loaded += (o, args) => textBox.Focus();

            msg.Dismissed += (s2, e2) =>
            {
                switch (e2.Result)
                {
                    case CustomMessageBoxResult.LeftButton:
                        TreeNode<Item> currentParent = null;
                        if (_nodesStack.Count > 0)
                            currentParent = _nodesStack.Peek();

                        int? id = null;
                        if (currentParent != null)
                            id = currentParent.Item.Id;

                        var item = new Item
                        {
                            Name = (msg.Content as TextBox).Text,
                            ParentId = id
                        };
                        (DataContext as ItemsViewModel).AddItem(item);
                        break;
                    case CustomMessageBoxResult.RightButton:
                    case CustomMessageBoxResult.None:
                        break;
                    default:
                        break;
                }
            };

            msg.Show();
        }

        void GoUpCurrentVisibleCategory()
        {
            var viewModel = (DataContext as ItemsViewModel);
            var rootNodes = viewModel.ItemsTree;
            if (_nodesStack.Count == 0)
            {
                treeListControl.ItemsSource = rootNodes;
                viewModel.SelectedNode = null;
                return;
            }

            // pop current visible item
            _nodesStack.Pop();

            // show upper item if can
            if (_nodesStack.Count == 0)
            {
                treeListControl.ItemsSource = rootNodes;
                viewModel.SelectedNode = null;
                return;
            }

            var upperNode = _nodesStack.Peek();
            viewModel.SelectedNode = upperNode;
            treeListControl.ItemsSource = upperNode.Children;
        }

        private void BindablePage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (_nodesStack.Count == 0)
            {
                e.Cancel = false;
                base.OnBackKeyPress(e);
            }
            else
            {
                e.Cancel = true;
                GoUpCurrentVisibleCategory();
            }
        }

        private void BindablePage_Loaded(object sender, RoutedEventArgs e)
        {
            if ((DataContext as ItemsViewModel).IsSelectItemPage)
                CreateSelectButton();
        }

        private void BindablePage_LayoutUpdated(object sender, EventArgs e)
        {
            if (selectNodeButton != null)
                selectNodeButton.IsEnabled = (DataContext as ItemsViewModel).SelectedNode != null;
        }

        private void BindablePage_BeginLayoutChanged(object sender, OrientationChangedEventArgs e)
        {

        }

        void MenuItem_Edit_OnClick(object sender, RoutedEventArgs args)
        {
            var item = (Item)(sender as MenuItem).Tag;
            var textBox = new TextBox { Text = item.Name };
            textBox.InputScope = new InputScope { Names = { new InputScopeName { NameValue = InputScopeNameValue.Chat } } };

            var msg = new CustomMessageBox()
            {
                Title = "Редактирование категории",
                Caption = "Введите наименование категории",
                Content = textBox,
                LeftButtonContent = "ОК",
                RightButtonContent = "Отмена",
                IsFullScreen = false
            };

            msg.Loaded += (o, eventArgs) => textBox.Focus();

            msg.Dismissed += (s2, e2) =>
            {
                switch (e2.Result)
                {
                    case CustomMessageBoxResult.LeftButton:
                        item.Name = textBox.Text;
                        (DataContext as ItemsViewModel).EditItem(item);
                        break;
                    case CustomMessageBoxResult.RightButton:
                    case CustomMessageBoxResult.None:
                        break;
                    default:
                        break;
                }
            };

            msg.Show();
        }
    }
}